package com.huazai.juc.bedroom.thread.past;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 手写自旋锁
 */
public class SpinLock {
    // 泛型里面装的是Thread，原子引用线程
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public void lock() throws InterruptedException {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + " come in");

        // 开始自旋，期望值为null，更新值是当前线程。
        while (! atomicReference.compareAndSet(null, thread)) {
            Thread.sleep(1000);
            System.out.println(thread.getName() + "正在自旋");
        }
        System.out.println(thread.getName() + "自旋成功");
    }

    public void unlock() {
        Thread thread = Thread.currentThread();

        // 线程使用完锁之后吧引用变为null
        atomicReference.compareAndSet(thread, null);
        System.out.println(thread.getName() + " invoke unlock");
    }

    public static void main(String[] args) throws InterruptedException {
        SpinLock spinLock = new SpinLock();
        new Thread(() -> {
            // 占有锁
            try {
                spinLock.lock();
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 释放锁
            spinLock.unlock();

        }, "ONE").start();

        // 让main线程暂停一秒，使得t1线程，先执行
        Thread.sleep(1000);

        new Thread(() -> {
            try {
                spinLock.lock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            spinLock.unlock();
        }, "TWO").start();
    }

}
